package com.gitee.feizns.dynamic.reflect;

import com.gitee.feizns.dynamic.ExUtils;
import com.gitee.feizns.dynamic.function.ThrowsThrowableSupplier;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;

/**
 * <b>通用反射操作工具类</b>
 *
 * @author feizns
 * @since 2022/10/14
 */
public class ReflectUtils {

    /**
     * <b>传入代码、这段代码将忽略因为没有方法、或是字段而抛出的异常</b>
     * @param supplier 代码段
     * @param <T> 原代码返回值类型
     * @return 原代码返回值
     */
    public static <T> T ignoreNoSuchMethodOrFieldException(ThrowsThrowableSupplier<T> supplier) {
        //如果是因为没有找到方法或者字段的异常则忽略该异常返回null
        return ExUtils.ignore(supplier, NoSuchFieldException.class, NoSuchMethodException.class);
    }

    /**
     * 判断类型或者字段上包含指定的注解
     * @param type 判断的类型
     * @param fieldName 在类型中查找的字段
     * @param annotation 查找的注解
     * @return 如果该类型上或者字段上有注解则返回true否则返回false
     */
    public static boolean isAnnotationPresentOnTypeOrField(Class<?> type, String fieldName, Class<? extends Annotation> annotation) {
        return type.isAnnotationPresent(annotation)
                || FieldUtils.find(type, fieldName).isAnnotationPresent(annotation);
    }

    /**
     * <b>设置accessibleObj的访问权限为可访问</b>
     * @see AccessibleObject
     * @param accessibleObj 可访问对象
     * @param <T> 可访问对象类型
     * @return 传入的对象
     */
    public static <T extends AccessibleObject> T accessible(T accessibleObj) {
        if ( accessibleObj != null )
            accessibleObj.setAccessible(true);
        return accessibleObj;
    }

}
